package lyf.framework.core;

import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * 扫包操作
 */
public class ClassScanner {
	public static List<Class<?>> scanClasses(String packageName) throws IOException, ClassNotFoundException {
		List<Class<?>> classList = new ArrayList<>();
		String path = packageName.replace(".", "/");
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		Enumeration<URL> resources = classLoader.getResources(path);
		while (resources.hasMoreElements()) {
			URL url = resources.nextElement();
			if (url.getProtocol().contains("jar")) {
				JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
				String jarFilePath = jarURLConnection.getJarFile().getName();
				classList.addAll(getClassesFromJar(jarFilePath, path));
			} else if (url.getProtocol().contains("file")) {
				String fiePath = url.getFile();
				// TODO 其他资源以后处理
				classList.addAll(doScanner(fiePath,packageName));
			}
		}

		return classList;
	}

	public static List<Class<?>> getClassesFromJar(String jarFilePath, String path)
			throws IOException, ClassNotFoundException {
		List<Class<?>> classes = new ArrayList<>();
		JarFile jarFile = new JarFile(jarFilePath);
		Enumeration<JarEntry> jarEntries = jarFile.entries();
		while (jarEntries.hasMoreElements()) {
			// jarEntry的标准格式举例：com/mooc/zbs/test/Test.class
			JarEntry jarEntry = jarEntries.nextElement();
			String entryName = jarEntry.getName();
			if (entryName.startsWith(path) && entryName.endsWith(".class")) {
				// 获取类的全限定名
				String classFullName = entryName.replace("/", ".").substring(0, entryName.length() - 6);
				classes.add(Class.forName(classFullName));
			}
		}
		return classes;
	}

	/**
	 * 根据配置扫描包内的待托管给ioc容器的类
	 */
	private static List<Class<?>> doScanner(String filePath, String path) throws ClassNotFoundException {
		List<Class<?>> classes = new ArrayList<>();
		File dir = new File(filePath);
		for (File file : dir.listFiles()) {
			String className = path + "." + file.getName().replace(".class", "");
			if (file.isDirectory()) {
				classes.addAll(doScanner(file.getPath(), className));
			} else {
				classes.add(Class.forName(className));
			}
		}
		return classes;
	}
}
